/*************************************************************************
 *                                                                       *
 * This file is part of the FreeMAPs distribution.  For full copyright   *
 * information, see COPYRIGHT and COPYING.LESSER.                        *
 *                                                                       *
 * Author:           sqbang                                              *
 * Email:            sqbang@ustc.edu                                     *
 * Date:             2014.09.24                                          *
 * Description:      geom point of dim = FREEMAPS_DIM                    *
 * Acknowledgements: This file is a copy from libMesh projection         *
 *                   with slight modification.                           *
 *                                                                       *
 *************************************************************************/
#if 0
#ifndef FreeMAPs_include_COMMON_tbox_Point_h
#define FreeMAPs_include_COMMON_tbox_Point_h

#include "FreeMAPsConfig.h"

//C++ headers
#include <vector>
#include <map>

//COMMON headers
#include "COMMON/base/Common.h"
//#include "COMMON/enum/Triple.h"
#include "COMMON/tbox/MathUtilities.h"

namespace FreeMAPs
{

//forward declarations
class InputDatabase;

/**
 * A \p Point defines a location in FREEMAPS_DIM real space.  Points
 * are always real-valued.
 *
 * it can be used as a vector.
 *
 * \author Benjamin S. Kirk, 2003.
 */
class Point
{
public:

    /**
     * Constructor.  By default sets all entries to 0.  Gives the point 0 in
     * \p LIBMESH_DIM dimensions.
     */
    inline
    Point (
        const double x = 0.,
        const double y = 0.,
        const double z = 0.);

    /**
     * Empty.
     */
    inline
    ~Point();

public:

    inline void
    create(
        const double x = 0.,
        const double y = 0.,
        const double z = 0.);

    /**
     * build a point by it's dim and p,
     * @note that we do not check the p's size, the user should ensure it.
     */
    inline void
    create(
        const double* p,
        const int dim);

    /**
     * from the map, read r.x, r.y and r.z's value to build a point
     */
    inline void
    create(
        const std::map<std::string, double>& m,
        const int dim);

    inline void
    create (
        const std::vector<double>& p);

    inline void
    clear();

    /**
     * @return true if the size if 1.
     */
    inline bool
    is_normalized() const;

    /**
     * @return a point with same direction and have size of 1.
     */
    inline void
    normalize();

    inline void
    scale (
        const double s);

    /**
     * @return the distance to p
     */
    inline double
    get_distance_to_point (
        const Point& p) const;

    inline double
    get_distance_to_point (
        const double x = 0.,
        const double y = 0.,
        const double z = 0.) const;

    inline double
    operator [](
        const int i)const;

    inline double&
    operator [](
        const int i);

    inline double
    operator ()(
        const int i)const;

    inline double&
    operator ()(
        const int i);
public:

    /**
     * trans the point to vector with size = dim.
     */
    std::vector<double>
    to_vector () const;

    void
    get_from_input (
        const InputDatabase* db,
        const std::string& key,
        const bool check_dim = true);

    friend class PointCmp;

    friend std::ostream&
    operator << (
        std::ostream& os,
        const Point& rhs);

private:

    std::vector<double> d_coords;
};



class PointCmp
{
public:

    /**
     * used to compare two node if thay have same coordinate
     * used in map
     */
    inline bool
    operator()(
        const Point& lhs,
        const Point& rhs) const;

    /**
     * check the PointCmp used in map.
     */
    static void
    check();
};

} //namespace FreeMAPs

#include "COMMON/tbox/Point.inl"

#endif //FreeMAPs_include_COMMON_geom_Point_h

#endif
